package com.platform.core.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.platform.comm.dto.DtoMapper;
import com.platform.comm.enums.YnEnum;
import com.platform.comm.exceptions.RestApiException;
import com.platform.comm.jwt.JwtTokenUtil;
import com.platform.comm.jwt.TokenInfoUtil;
import com.platform.comm.service.impl.CommonBizImpl;
import com.platform.core.entity.NcloudSysNameStandardEntity;
import com.platform.core.entity.QNcloudSysNameStandardEntity;
import com.platform.core.repository.NcloudSysNameStandardRepository;
import com.platform.core.service.NcloudSysNameStandardService;
import com.platform.dto.NcloudSysNameStandardDto;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.querydsl.QSort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Description: NcloudSysNameStandard-业务接口实现类
 *
 * @author Coder
 */
@Slf4j
@Service
public class NcloudSysNameStandardServiceImpl extends CommonBizImpl<NcloudSysNameStandardRepository, NcloudSysNameStandardEntity, String> implements NcloudSysNameStandardService {

    private final QNcloudSysNameStandardEntity qNcloudSysNameStandard = QNcloudSysNameStandardEntity.ncloudSysNameStandardEntity;
    private final DtoMapper mapper;
    private final TokenInfoUtil tokenInfoUtil;

    public NcloudSysNameStandardServiceImpl(NcloudSysNameStandardRepository ncloudSysNameStandardRepository, DtoMapper mapper,
                                            TokenInfoUtil tokenInfoUtil) {
        super(ncloudSysNameStandardRepository);
        this.mapper = mapper;
        this.tokenInfoUtil = tokenInfoUtil;
    }

    @Override
    public Page<NcloudSysNameStandardDto> search(Predicate predicate, Pageable pageable) {
        Page<NcloudSysNameStandardEntity> page = queryByPage(predicate, pageable);
        return page.map(entity -> mapper.map(entity, NcloudSysNameStandardDto.class));
    }

    @Override
    public NcloudSysNameStandardDto detail(String id) {
        return mapper.map(fetchById(id), NcloudSysNameStandardDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public NcloudSysNameStandardDto add(NcloudSysNameStandardDto NcloudSysNameStandardDto) {
        if (!checkByName(NcloudSysNameStandardDto)) {
            throw new RestApiException("规范名称请勿重复");
        }
        NcloudSysNameStandardEntity entity = mapper.map(NcloudSysNameStandardDto, NcloudSysNameStandardEntity.class);
        JwtTokenUtil.JwtUser user = tokenInfoUtil.getUser();
        entity.setCreateBy(user.getId());
        entity.setCreateName(user.getUsername());
        entity.setCreateDate(LocalDateTime.now());
        entity.setUpdateBy(user.getId());
        entity.setUpdateName(user.getUsername());
        entity.setUpdateDate(LocalDateTime.now());
        entity.setStatus(YnEnum.Y.getCode());
        entity.setFlag(YnEnum.N.getCode());
        NcloudSysNameStandardEntity NcloudSysNameStandardEntity = saveEntity(entity);
        return mapper.map(NcloudSysNameStandardEntity, NcloudSysNameStandardDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public NcloudSysNameStandardDto update(NcloudSysNameStandardDto NcloudSysNameStandardDto) {
        if (!checkByName(NcloudSysNameStandardDto)) {
            throw new RestApiException("规范名称请勿重复");
        }
        NcloudSysNameStandardEntity entity = fetchById(NcloudSysNameStandardDto.getId());
        //不copy空值
        BeanUtil.copyProperties(NcloudSysNameStandardDto, entity, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        JwtTokenUtil.JwtUser user = tokenInfoUtil.getUser();
        entity.setUpdateBy(user.getId());
        entity.setUpdateName(user.getUsername());
        entity.setUpdateDate(LocalDateTime.now());
        NcloudSysNameStandardEntity NcloudSysNameStandardEntity = saveEntity(entity);
        return mapper.map(NcloudSysNameStandardEntity, NcloudSysNameStandardDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(String id) {
        //repository.deleteById(id);
        NcloudSysNameStandardEntity entity = fetchById(id);
        if(entity==null){
            return;
        }
        NcloudSysNameStandardDto dto = mapper.map(entity, NcloudSysNameStandardDto.class);
        dto.setStatus(YnEnum.N.getCode());
        dto.setFlag(YnEnum.Y.getCode());
        update(dto);
    }

    @Override
    public Page<NcloudSysNameStandardDto> searchByExampleForPage(NcloudSysNameStandardDto NcloudSysNameStandardDto, Pageable pageable) {
        PageRequest pageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(),
                QSort.by(qNcloudSysNameStandard.updateDate.desc(), qNcloudSysNameStandard.id.asc()));
        Page<NcloudSysNameStandardEntity> page = queryByPage(build(NcloudSysNameStandardDto), pageRequest);
        return page.map(entity -> mapper.map(entity, NcloudSysNameStandardDto.class));
    }

    @Override
    public List<NcloudSysNameStandardDto> searchByExampleForList(NcloudSysNameStandardDto NcloudSysNameStandardDto) {
        return this.queryAll(build(NcloudSysNameStandardDto), QSort.by(qNcloudSysNameStandard.updateDate.desc(), qNcloudSysNameStandard.id.desc()))
                .stream().map(entity -> mapper.map(entity, NcloudSysNameStandardDto.class))
                .collect(Collectors.toList());
    }

    /**
     * 进行校验名称不能重复
     *
     * @return true:允许添加 false:不允许添加
     */
    @Override
    public boolean checkByName(NcloudSysNameStandardDto ncloudSysNameStandardDto) {
        String id = ncloudSysNameStandardDto.getId();
        NcloudSysNameStandardDto params = new NcloudSysNameStandardDto();
        params.setName(ncloudSysNameStandardDto.getName());
        List<NcloudSysNameStandardDto> list = searchByExampleForList(params);
        if (list == null || list.size() <= 0) {
            return true;
        } else {
            if (id == null) {
                return false;
            }
            return id.equals(list.get(0).getId());
        }
    }

    /**
     * 统一组装查询条件
     *
     * @param ncloudSysNameStandardDto 参数
     * @return 返回 BooleanBuilder 查询条件
     */
    private BooleanBuilder build(NcloudSysNameStandardDto ncloudSysNameStandardDto) {
        BooleanBuilder booleanBuilder = new BooleanBuilder(qNcloudSysNameStandard.flag.eq(YnEnum.N.getCode()));
        if (StringUtils.isNotBlank(ncloudSysNameStandardDto.getId())) {
            booleanBuilder.and(qNcloudSysNameStandard.id.eq(ncloudSysNameStandardDto.getId()));
        }
        /**
         * 规范名称
         */
        if (StringUtils.isNotBlank(ncloudSysNameStandardDto.getName())) {
            booleanBuilder.and(qNcloudSysNameStandard.name.contains(ncloudSysNameStandardDto.getName()));
        }
        /**
         * 适用对象键 1:数据模型 2:采报表单 3：文件
         */
        if (StringUtils.isNotBlank(ncloudSysNameStandardDto.getApplicableKey())) {
            booleanBuilder.and(qNcloudSysNameStandard.applicableKey.eq(ncloudSysNameStandardDto.getApplicableKey()));
        }
        /**
         * 状态
         */
        if (StringUtils.isNotBlank(ncloudSysNameStandardDto.getStatus())) {
            booleanBuilder.and(qNcloudSysNameStandard.status.eq(ncloudSysNameStandardDto.getStatus()));
        }
        if (StringUtils.isNotBlank(ncloudSysNameStandardDto.getRemark())) {
            //备注
            booleanBuilder.and(qNcloudSysNameStandard.remark.contains(ncloudSysNameStandardDto.getRemark()));
        }
        return booleanBuilder;
    }
}
